using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.Profile;
using Commerce.Common;
using Commerce.Providers;
using Commerce.PayPal;
using umbraco.providers.members;
using umbraco.cms.businesslogic.member;

namespace CommerceForUmbraco.usercontrols
{
    public partial class MultiPageCheckout1 : System.Web.UI.UserControl
    {
        // the current order - for shipping and tax calcs
        protected Order currentOrder = null;

        // the Umbraco Member Profile
        protected CommerceForUmbraco.profile.UmbracoProfile umbProfile;

        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                if (!IsPostBack)
                {
                    string qs = HttpContext.Current.Request.QueryString.ToString();
                    string redirectPage = "";

                    // redirect to configured checkoutUrl - unless it's running on a specified test server or localhost
                    if ((!HttpContext.Current.Request.Url.ToString().Contains(Utility.GetTestHostName()))
                        && (!HttpContext.Current.Request.Url.ToString().Contains("localhost")))
                    {
                        //  set to checkout URL as defined in web.config
                        int removeStart = Context.Request.Url.AbsoluteUri.IndexOf('&');
                        string compareUrl = "";

                        if (removeStart > 0)
                            compareUrl = Context.Request.Url.AbsoluteUri.Remove(removeStart);
                        else
                            compareUrl = Context.Request.Url.AbsoluteUri;

                        string[] requestPage = compareUrl.Split('/');
                        string[] configPage = Utility.GetCheckoutUrl().Split('/');

                        if (requestPage[requestPage.Length - 1] != configPage[configPage.Length - 1])
                        {
                            redirectPage = Utility.GetCheckoutUrl() + "?" + qs;
                            Response.Redirect(redirectPage);
                        }
                    }
                }

                // get the order and set the order display
                SetCurrentOrder();
                lblOrderItems.Text = currentOrder.mcOrderItemsTable();
                if (currentOrder.CouponCodes.Length > 0)
                {
                    CouponCode.Text = currentOrder.CouponCodes;
                }

            }
            catch (Exception ex)
            {
                message.Text = "We're sorry, an error occured.<br />" + ex.Message;
            }
        }

        #region button handlers

        /// <summary>
        /// Handles the Click event of the emailContinue control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void emailContinue_Click(object sender, EventArgs e)
        {
            try
            {
                
                // encode the user provided email address - used to create new members
                string encEmail = HttpUtility.HtmlEncode(Email.Text);

                // set up the order
                SetCurrentOrder();

                // apply coupon
                if (CouponCode.Text.Length > 0)
                {
                    try
                    {
                        Commerce.Promotions.Coupon current = Commerce.Promotions.Coupon.GetCoupon(CouponCode.Text);
                        if (!(currentOrder.CouponCodes.Length > 0))
                        {
                            current.ApplyCouponToOrder(currentOrder);
                            lblOrderItems.Text = currentOrder.mcOrderItemsTable();
                        }
                        
                        
                    }
                    catch (ArgumentException ae)
                    {
                        throw new Exception(ae.Message);
                    }
                }

                // verify one option was selected
                if (paymentTypeList.SelectedIndex == -1)
                    throw new Exception("Please select a payment type before continuing.");

                if (paymentTypeList.SelectedValue == "pp")
                {
                    SetExpressCheckout();
                }
                else
                {
                    // look for profile - create new profile if not found
                    SetProfile(Email.Text);  
                    Member mu = Member.GetMemberFromEmail(Email.Text);
                    
                    if (mu == null)
                    {
                        //create a new member with the supplied email and temporary password
                        string pwd = Membership.GeneratePassword(8, 1);
                        string memberType = "";
                        string memberGroup = "";
                        string domain = HttpContext.Current.Request.Url.DnsSafeHost;
                        domain = "commerceDomainConfiguration/" + domain;

                        // get the related config section and orderPrefix setting
                        System.Collections.IDictionary stsh =
                            (System.Collections.IDictionary)System.Configuration.ConfigurationManager.GetSection(domain);

                        // make sure we have a section for this domain
                        if (stsh != null)
                        {
                            memberType = stsh["memberType"].ToString();
                            memberGroup = stsh["memberGroup"].ToString();
                        }

                        Member m = Member.MakeNew(encEmail, encEmail, MemberType.GetByAlias(memberType), new umbraco.BusinessLogic.User(0));
                        m.Password = pwd;

                        MemberGroup Group = MemberGroup.GetByName(memberGroup);
                        if (Group != null)
                            m.AddGroup(Group.Id);

                        m.Save();
                        // update the original Member object
                        mu = m;
                    }

                    // update the order with the current user name
                    currentOrder.UserName = mu.Text;
                    currentOrder.Save();

                    // update the order with the current user name
                    if (mu != null)
                    {
                            HttpContext.Current.Response.Cookies["shopperID"].Domain = Utility.GetBaseDomain();
                            HttpContext.Current.Response.Cookies["shopperID"].Value = currentOrder.UserName;
                            HttpContext.Current.Response.Cookies["shopperID"].Expires = DateTime.Today.AddDays(365);
                    }
                }

                // transfer to part 2 - address entry
                Response.Redirect("checkout2.aspx", true);

            }
            catch (Exception ex)
            {
                message.Text = "We're sorry, an error occured.<br />" + ex.Message;        
            }
        }

        protected void ActivateCouponCode_Click(object sender, EventArgs e)
        {
            // apply coupon
            if (CouponCode.Text.Length > 0)
            {
                try
                {
                    Commerce.Promotions.Coupon current = Commerce.Promotions.Coupon.GetCoupon(CouponCode.Text);
                    if (!(currentOrder.CouponCodes.Length > 0))
                    {
                        current.ApplyCouponToOrder(currentOrder);
                        lblOrderItems.Text = currentOrder.mcOrderItemsTable();
                    }


                }
                catch (ArgumentException ae)
                {
                    CouponCodeStatus.Text = ae.Message;
                    
                }
            }
        }

        #endregion

        #region checkout utility methods

        void SetOrderInfo()
        {
            currentOrder.ShippingAddress = umbProfile.GetCommerceShippingAddress();
            currentOrder.BillingAddress = umbProfile.GetCommerceBillingAddress();

            // get tax
            currentOrder.TaxAmount = GetCurrentOrderTax(umbProfile.BillingStateOrRegion);

            if (currentOrder.BillingAddress != null)
            {
                currentOrder.FirstName = currentOrder.BillingAddress.FirstName;
                currentOrder.LastName = currentOrder.BillingAddress.LastName;
                currentOrder.Email = currentOrder.BillingAddress.Email;
            }

        }

        public void SetCurrentOrder()
        {
            if (currentOrder == null)
                currentOrder = OrderController.GetCurrentOrder();
        }

        public void SetProfile(string userName)
        {
            // set the Umbraco profile
            umbProfile = new CommerceForUmbraco.profile.UmbracoProfile(userName);
        }

        protected string TrimData(string data, int length)
        {
            int totalLength = data.Length;

            if (totalLength > length)
            {
                return data.Substring(0, length);
            }
            else
            {
                return data;
            }
        }

        PackageInfo LoadPackage()
        {
            //Create shipping package
            SiteConfig.Load();

            PackageInfo package = new PackageInfo();
            package.FromZip = SiteConfig.ShipFromZip;
            package.FromCountryCode = SiteConfig.ShipFromCountryCode;

            Address shipAdd = umbProfile.GetCommerceShippingAddress();
            package.ToZip = shipAdd.Zip;
            package.ToCountryCode = shipAdd.Country;

            package.Weight = currentOrder.GetItemsWeight();
            package.Width = Convert.ToInt16(currentOrder.GetTotalWidth());
            package.Height = Convert.ToInt16(currentOrder.GetTotalHeight());
            package.Length = Convert.ToInt16(currentOrder.GetMaxLength());
            package.DimensionUnit = SiteConfig.DimensionUnit;
            package.PackagingBuffer = SiteConfig.ShipPackagingBuffer;

            return package;
        }

        /// <summary>
        /// Gets the current order tax based on supplied State Code
        /// </summary>
        /// <returns>Tax Amount</returns>
        protected decimal GetCurrentOrderTax(string StateCode)
        {
            decimal dTax = 0;

            try
            {
                USState state = (USState)Utility.StringToEnum(typeof(Commerce.Common.USState), StateCode);

                dTax = OrderController.CalculateTax(state, currentOrder.CalculateSubTotal(), currentOrder.ShippingAmount);

                return dTax;
            }
            catch
            {
                return 0;
            }
        }

    #endregion

        #region PayPal Express Checkout

        protected APIWrapper GetPPWrapper()
        {
            SiteConfig.Load();

            APIWrapper wrapper =
              new APIWrapper(SiteConfig.PayPalAPIAccountName
                    , SiteConfig.PayPalAPIAccountPassword
                    , SiteConfig.APIsignature
                    , (CurrencyCode)Enum.Parse(typeof(CurrencyCode),SiteConfig.defaultCurrencyCode)
                    , SiteConfig.APIIsLive);

            return wrapper;
        }

        protected void SetExpressCheckout()
        {
            try
            {
                // in case the user has entered an address
                SetProfile(Email.Text);

                // SetExpressCheckout
                APIWrapper wrapper = GetPPWrapper();

                // set email if we have one
                string sEmail = Email.Text;

                string successURL = Utility.GetPayPalExpressCheckoutSuccessUrl();
                string failURL = Utility.GetPayPalExpressCheckoutFailUrl();
                string sUrl = "";
                string ppToken = "";

                if (currentOrder.Items.Count > 0)
                {
                    ppToken = wrapper.SetExpressCheckout(sEmail, currentOrder.CalculateSubTotal(),
                      successURL, failURL, false, currentOrder.ShippingAddress);

                    if (ppToken.ToLower().Contains("error"))
                    {
                        throw new Exception("PayPal has returned an error message: " + ppToken.ToString());
                    }
                    else
                    {

                        sUrl = "https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=" + ppToken;

                        if (!SiteConfig.APIIsLive)
                        {
                            sUrl = "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=" + ppToken;
                        }

                        try
                        {
                            Response.Redirect(sUrl, false);
                            Response.End();
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                    }

                }
                else
                {
                    // send back to the cart page
                    Response.Redirect(Utility.GetCartUrl(), false);
                }

            }
            catch (Exception)
            {
                throw;
            }
        }

        #endregion

        

    }
}